#!/usr/bin/python3
"""_summary_

    Returns:
        _type_: _description_
"""
# -*- coding:utf-8 -*-
#
# File Name:
# @Author:  paddy
# @Email:   3988263@qq.com
# @Time:    ${DATE} ${TIME}
# Project: ${PROJECT_NAME}
# ---------------------说明--------------------------
#
# ---------------------------------------------------
# '''
# MqttManager 用来启动MQTT brocker的监听和管理
# 主要功能：
#     1、监听和打印
#     2、把AGV的状态信息收集，整合成Json格式的数据
#     3、连接redis，将Json对象写入缓存
#     4、提供读取接口，返回Json格式
# 主要数据结构
#     [AGV_ID][AGV_speed][AGV_XYZ][...]
# '''

from threading import Thread
import json
import time
import logging
import random
from dataclasses import dataclass
import paho.mqtt.client as mqtt
from service.myexception import error_management
from service.base import MyBase
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
logger.addHandler(console)
ISSTOP = False


@dataclass
class DeviceAttrib:
    """设备属性对象
    """
    mqtt_host: str = None
    mqtt_port: str = None
    topic: str = "device/attributes"
    client_id: str = "paddy_demo_test"
    username: str = None
    password: str = None
    device_id: str = None
    device_name: str = None
    token: str = None
    asset_name: str = None

    @property
    def subscribe(self):
        """_summary_

        Returns:
            _type_: _description_
        """
        value = str(self.topic) + str('/') + str(self.device_id)
        return str(value)


class MqttManager(Thread, MyBase):
    """针对某个单一设备的随机仿真

    Args:
        Thread (_type_): _description_
    """
    client = None
    deviceattrib = None

    # 当只有一次的时候，是初始化重连接(这个大坑没弄明白，为了优雅的停止，先弄个变量控制)，连续超过2次，则是真的连接错误
    connect_fail = 0

    def __init__(self, subwebapi, deviceattr):
        super().__init__()
        MyBase.__init__(self, subwebapi)  # 重构run函数必须要写
        self.deviceattrib = deviceattr
        self.disconnected = (False, None)

    def __del__(self): ...

    @error_management
    def on_message(self, mosq, obj, msg):
        """_summary_

        Args:
            mosq (_type_): _description_
            obj (_type_): _description_
            msg (_type_): _description_
        """
        print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
        if mosq or obj:
            pass

    # @error_management
    def on_publish(self, mqttc, obj, mid):
        """_summary_

        Args:
            mqttc (_type_): _description_
            obj (_type_): _description_
            mid (_type_): _description_
        """
        # print("mid: " + str(mid))
        if mqttc or obj:
            pass

    def on_connect(self, mqttc, obj, flags, rc):
        # 当只有一次的时候，是初始化重连接，连续超过2次，则是真的连接错误
        if rc > 0:
            self.connect_fail += 1
        # 当只有一次的时候，是初始化重连接，连续超过2次，则是真的连接错误
        if self.connect_fail > 1:
            self.disconnected = True, '连接失败'
            self.client.disconnect()

    # @error_management
    def serialize(self):
        """_summary_

        Returns:
            _type_: _description_
        """

        messages = {
            "二氧化碳(CO2": f"{random.uniform(150.000, 250.000):0.4f}",
            "甲烷(CH4)": f"{random.uniform(50, 100):0.4f}",
            "氧化亚氮(N2O)": f"{random.uniform(100, 200):0.4f}",
            "电池电量": f"{random.uniform(10, 100):0.4f}",
            }
        # logger.info(messages)
        return messages

    @error_management
    def connect_mqtt(self):
        """_summary_
        """
        self.client = mqtt.Client(self.deviceattrib.client_id)
        # self.client.enable_logger(logger)
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.on_publish = self.on_publish
        self.client.connect(
            self.deviceattrib.mqtt_host,
            int(self.deviceattrib.mqtt_port))
        self.client.username_pw_set(
            self.deviceattrib.username,
            self.deviceattrib.password)
        self.client.loop_start()

    @error_management
    def disconnect(self):
        """给当前线程发送终止命令
        """
        # logger.info('线程 %r 执行完毕', self.getName)
        self.disconnected = True, self.getName
        self.client.disconnect()

    @property
    def getName(self):
        """当前线程名称

        Returns:
            _type_: _description_
        """
        return f'MqttManager-{self.deviceattrib.device_id}'

    def run(self):

        self.connect_mqtt()
        while not self.disconnected[0]:
            msg = self.serialize()
            logger.info(
                '设备id: %r,发送: %r',
                self.deviceattrib.username,
                msg
                )
            self.client.publish(
                self.deviceattrib.topic,
                json.dumps(msg))  # 发布状态 或者 弄成json文件
            # infot.wait_for_publish()
            time.sleep(2)
        logger.info("关闭线程: %r", self.disconnected[1])
